package com.aiex.framework.db.config.base.mapper;

import com.aiex.framework.db.config.base.PageDTO;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.exception.FlexAssert;
import com.mybatisflex.core.field.FieldQueryBuilder;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;

import java.util.function.Consumer;

public interface FlexBaseMapper<T> extends BaseMapper<T> {

    /**
     * 分页查询。尽可能少依赖第三方，返回转换为自定义分页
     *
     * @param pageNumber   当前页码
     * @param pageSize     每页的数据量
     * @param queryWrapper 条件
     * @return 分页数据
     */
    default PageDTO<T> page(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
        Page<T> page = new Page<>(pageNumber, pageSize);
        Page<T> pageResult = paginate(page, queryWrapper);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询。尽可能少依赖第三方，返回转换为自定义分页
     * @param page
     * @param queryWrapper
     * @param asType
     * @return
     */
    default PageDTO<T> pageWithRelationsAs(Page<T> page, QueryWrapper queryWrapper, Class<T> asType) {
        Page<T> pageResult = paginateWithRelationsAs(page, queryWrapper, asType);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询，及其 Relation 字段内容。
     *
     * @param pageNumber   当前页码
     * @param pageSize     每页的数据量
     * @param queryWrapper 条件
     * @return 分页数据
     */
    default PageDTO<T> pageWithRelations(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
        Page<T> page = new Page<>(pageNumber, pageSize);
        Page<T> pageResult = paginateWithRelations(page, queryWrapper);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询。
     *
     * @param pageNumber      当前页码
     * @param pageSize        每页的数据量
     * @param whereConditions 条件
     * @return 分页数据
     */
    default PageDTO<T> page(Number pageNumber, Number pageSize, QueryCondition whereConditions) {
        Page<T> page = new Page<>(pageNumber, pageSize);
        Page<T> pageResult = paginate(page, new QueryWrapper().where(whereConditions));
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询，及其 Relation 字段内容。
     *
     * @param pageNumber      当前页码
     * @param pageSize        每页的数据量
     * @param whereConditions 条件
     * @return 分页数据
     */
    default PageDTO<T> pageWithRelations(Number pageNumber, Number pageSize, QueryCondition whereConditions) {
        Page<T> page = new Page<>(pageNumber, pageSize);
        Page<T> pageResult = paginateWithRelations(page, new QueryWrapper().where(whereConditions));
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询。
     *
     * @param pageNumber   当前页码
     * @param pageSize     每页的数据量
     * @param totalRow     数据总量
     * @param queryWrapper 条件
     * @return 分页数据
     */
    default PageDTO<T> page(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
        Page<T> pageResult = paginate(page, queryWrapper);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询，及其 Relation 字段内容。
     *
     * @param pageNumber   当前页码
     * @param pageSize     每页的数据量
     * @param totalRow     数据总量
     * @param queryWrapper 条件
     * @return 分页数据
     */
    default PageDTO<T> pageWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
        Page<T> pageResult = paginateWithRelations(page, queryWrapper);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询。
     *
     * @param pageNumber      当前页码
     * @param pageSize        每页的数据量
     * @param totalRow        数据总量
     * @param whereConditions 条件
     * @return 分页数据
     */
    default PageDTO<T> page(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) {
        FlexAssert.notNull(whereConditions, "whereConditions");
        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
        Page<T> pageResult = paginate(page, new QueryWrapper().where(whereConditions));
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询，及其 Relation 字段内容。
     *
     * @param pageNumber      当前页码
     * @param pageSize        每页的数据量
     * @param totalRow        数据总量
     * @param whereConditions 条件
     * @return 分页数据
     */
    default PageDTO<T> pageWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) {
        FlexAssert.notNull(whereConditions, "whereConditions");
        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
        Page<T> pageResult = paginateWithRelations(page, new QueryWrapper().where(whereConditions));
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询。
     *
     * @param page         包含了页码、每页的数据量，可能包含数据总量
     * @param queryWrapper 条件
     * @return page 数据
     */
    default PageDTO<T> page(Page<T> page, QueryWrapper queryWrapper) {
        Page<T> pageResult = paginateAs(page, queryWrapper, null);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询。
     *
     * @param page         包含了页码、每页的数据量，可能包含数据总量
     * @param queryWrapper 条件
     * @param consumers    字段查询
     * @return page 数据
     */
    default PageDTO<T> page(Page<T> page, QueryWrapper queryWrapper, Consumer<FieldQueryBuilder<T>>... consumers) {
        Page<T> pageResult = paginateAs(page, queryWrapper, null, consumers);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询，及其 Relation 字段内容。
     *
     * @param page         包含了页码、每页的数据量，可能包含数据总量
     * @param queryWrapper 条件
     * @return 分页数据
     */
    default PageDTO<T> pageWithRelations(Page<T> page, QueryWrapper queryWrapper) {
        Page<T> pageResult = paginateWithRelationsAs(page, queryWrapper, null);
        return PageDTO.of(pageResult);
    }

    /**
     * 分页查询，及其 Relation 字段内容。
     *
     * @param page         包含了页码、每页的数据量，可能包含数据总量
     * @param queryWrapper 条件
     * @param consumers    字段查询
     * @return 分页数据
     */
    default PageDTO<T> pageWithRelations(Page<T> page, QueryWrapper queryWrapper, Consumer<FieldQueryBuilder<T>>... consumers) {
        Page<T> pageResult = paginateWithRelationsAs(page, queryWrapper, null, consumers);
        return PageDTO.of(pageResult);
    }







}
